package com.maben.udp.test003.netty_client;

import io.netty.bootstrap.Bootstrap;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;

/**
 * 客户端：NioSocketChannel这里使用的是长连接
 */
public class Client {
    /**
     * 端口号
     */
    private int port;
    /**
     * host
     */
    private String host = "127.0.0.1";
    /**
     * 通道
     */
    private Channel channel;

    public Client(int port) {
        this.port = port;
    }

    public void run() throws InterruptedException {
        //负责装客户端的事件处理线程池
        EventLoopGroup clientWorker = new NioEventLoopGroup();
        try {
            //netty客户端引导启动器
            Bootstrap client = new Bootstrap();
            //把事件处理线程池添加进启动引导器
            client.group(clientWorker);
            //设置通道的建立方式,这里采用Nio的通道方式来建立请求连接
            client.channel(NioSocketChannel.class);
            //此处添加客户端的通道处理器
            client.handler(new ChannelInitializer<SocketChannel>() {
                @Override
                protected void initChannel(SocketChannel socketChannel) throws Exception {
                    socketChannel.pipeline().addLast(new MyClientHandler());
                }
            });
            //客户端绑定端口并且开始发起连接请求
            ChannelFuture future = client.connect(host, port).sync();
            if (future.isSuccess()) {
                System.out.println("client started!");
            }
            //将通道设置好, 以便外面获取
            this.channel = future.channel();
            //关闭客户端
            future.channel().closeFuture().sync();
            System.out.println("client is stopping!");
        } finally {
            //关闭事件处理组
            clientWorker.shutdownGracefully();
            System.out.println("client stopped!");
        }
    }

    /**
     * 向外暴露获取通道的方法
     */
    public Channel getChannel() {
        return this.channel;
    }
}
